/*
 * @Author: llch
 * @Date: 2020-09-15 21:21:09
 * @LastEditTime: 2021-04-18 09:00:28
 * @LastEditors: Please set LastEditors
 * @Description: In User Settings Edit
 * @FilePath: \tower_defense_demo\assets\scripts\modules\ugame.ts
 */

/**
 * // 玩家数据
 *      chip: 2000,     // 玩家的金币
 *      blood: 20,      // 玩家血量
 * 
 * // 玩家闯关的数据，如果通过，根据成绩来评价获得的最好星数，3颗、2颗、1颗
 *      level_info: [0, 0, 0, ..., 0]   // 总共19关
 *      star_num: 12                    // 玩家当前获得了多少颗星
 *      star_total: 77                  // 玩家总共可以获得星
 * 
 * // 塔技能级别    4种防御塔，2种技能
 * tower_skills_level: {
 *      arrow_level: 1,         // 弓箭
 *      infantry_level: 1,      // 兵营
 *      warlock_level: 1,       // 术士
 *      connon_level: 1,        // 炮弹
 *      
 *      skills_bomb_skill,      // 技能陨石炸弹
 *      skills_thunder_skill,   // 技能雷击
 * }    
 * 
 * // 技能升级  升级消耗星星数
 * tower_skills_upgrade_config: {
 *      arrow_tower: [0, 1, 1, 2, 2, 3],        // 弓箭塔
 *      infantry_tower: [0, 1, 1, 2, 2, 3],     // 兵营塔
 *      warlock_tower: [0, 1, 1, 2, 2, 3],      // 术士塔
 *      connon_tower: [0, 1, 1, 2, 2, 3],       // 炮弹塔
 * 
 *      skills_bomb: [0, 1, 1, 2, 2, 3],        // 技能陨石炸弹
 *      skills_thunder: [0, 1, 1, 2, 2, 3],     // 技能雷击
 * }
 * 
 * // 技能冷却时间  
 * skills_cooldown_config: {
 *      skills_bomb_cooldown: [45, 45, 45, 35, 25, 25],
 *      skills_thunder_cooldown: [20, 20, 20, 15, 10, 10],
 * }
 * 
 */


class UGame {
    // 全局单例
    public static readonly Instance: UGame = new UGame();

    // 属性数据
    public user_data: object = {
        0: null, // 玩家1的数据
        1: null, // 玩家2的数据
        2: null, // 玩家3的数据;
    };
    public cur_user: number = 0;    // 当前玩家数据，默认0
    public tower_skills_upgrade_config: object = {  // 技能升级  升级消耗星星数
        0: [0, 1, 1, 2, 2, 3],      // 弓箭塔
        1: [0, 1, 1, 2, 2, 3],      // 兵营塔
        2: [0, 1, 1, 2, 2, 3],      // 术士塔
        3: [0, 1, 1, 2, 2, 3],      // 炮弹塔
        
        4: [0, 1, 1, 2, 2, 3],      // 技能陨石炸弹
        5: [0, 1, 1, 2, 2, 3],      // 技能雷击
    };
    public cur_playing_level: number = 0;   // 当前游戏关卡
    public is_game_started: boolean = false;    // 是否在游戏中
    public is_game_paused: boolean = false;     // 游戏是否暂停
    public enemy_arr: Array<cc.Node> = [];      // 保存敌人数据
    public map_road_data = undefined;

    // 构造函数 
    constructor() {
        // 初始化数据
        this.init_user_data();
    }

    // ==========================初始化=======================
    // 初始化用户数据
    public init_user_data(): void {
        // 加载本地数据
        this._load_user_data();
        // 计算用户星数
        this._compute_user_star();
    }

    // ==========================敌人操作=======================
    // 1. 清除敌人数组
    public clear_enemy_arr(): void {
        this.enemy_arr = [];
    }

    // 2. 判断是否有敌人
    public is_enemy_active(enemy: cc.Node): boolean {
        const index = this.enemy_arr.indexOf(enemy);
        if (index < 0 || index >= this.enemy_arr.length) {
            return false;
        }
        return true;
    }

    // 3. 添加敌人
    public add_enemy(enemy: cc.Node): void {
        this.enemy_arr.push(enemy);
    }

    // 4. 移除敌人
    public remove_enemy(enemy: cc.Node): void {
        const index = this.enemy_arr.indexOf(enemy);
        this.enemy_arr.splice(index, 1);
    }

    // 5. 获取敌人合集
    public get_enemy_arr(): Array<cc.Node> {
        return this.enemy_arr;
    }

    // 6. 筛选处于塔攻击范围内的敌人
    public search_enemy(center_pos: cc.Vec2, search_r: number): any {
        for (let i = 0; i < UG.enemy_arr.length; i++) {
            // 判断敌人与塔中心点的距离是否处于塔的攻击范围内
            let enemy_pos: cc.Vec2 = UG.enemy_arr[i].getPosition();
            let _pos: cc.Vec2 = enemy_pos.sub(center_pos);
            let range: number = _pos.mag();
            if (search_r >= range) {
                return UG.enemy_arr[i];
            }
        }
        return null;
    }

    // ==========================消耗============================
    // 金币消耗 + -
    public add_chip(chip: number): void {
        const cur_user_data = this.get_cur_user();
        cur_user_data.chip += chip;
        this.sync_user_data();// 同步保存数据
    }

    // 获取金币数
    public get_uchip(): number {
        const cur_user_data = this.get_cur_user();
        return cur_user_data.chip;
    }

    // ========================游戏地图数据操作====================
    // 设置地图数据
    public set_map_road_data(road_data): void {
        this.map_road_data = road_data;
    }

    // 获取地图数据
    public get_map_road_data() {
        return this.map_road_data;
    }
    
    // ======================设置当前数据============================
    // 设置哪个用户信息进入游戏
    public set_cur_user(user_index: number): void {
        if (user_index < 0 || user_index > 3) {
            user_index = 0;
        }
        this.cur_user = user_index;
    }

    // 设置当前关卡索引
    public set_cur_level(level: number): void {
        this.cur_playing_level = level
    }

    // 同步保存数据
    public sync_user_data(): void {
        const json_str = JSON.stringify(this.user_data);
        cc.sys.localStorage.setItem("user_data", json_str);
    }

    // ======================获取当前数据==========================
    // 获取当前游戏用户的数据
    public get_cur_user() {
        return this.user_data[this.cur_user];
    }

    // 获取当前关卡索引
    public get_cur_level(): number {
        // return this.cur_playing_level;
        return 0;
    }

    // 获取当前

    // ==========================私有=============================
    // 从本地加载用户数据
    private _load_user_data(): void {
        let local_user_data: string = cc.sys.localStorage.getItem("user_data");
        if (local_user_data) {  // 本地有数据
        // if (0) {    
            this.user_data = JSON.parse(local_user_data);
            return;
        }
        
        // 本地没有数据，初始化数据
        this.user_data = {
            0: { // 第0个玩家的数据
                chip: 5000,
                blood: 20,
                level_info: [3, 3, 3, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], // 19关全部为0
                star_num: 10,
                star_total: 77,
                
                // 4个塔技能设置，2个用户技能
                skill_level_info: [2, 0, 0, 0, 0, 0], // [skill0, skill1, skill2, skill, skill2, skill]
            },
            
            1: {
                chip: 5000,
                blood: 20,
                level_info: [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], // 19关全部为0
                star_num: 0,
                star_total: 77,
                skill_level_info: [0, 0, 0, 0, 0, 0], // [skill0, skill1, skill2, skill, skill2, skill]
            }, 
            
            2: {
                chip: 5000,
                blood: 20,
                level_info: [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], // 19关全部为0
                star_num: 0,
                star_total: 77,
                skill_level_info: [0, 0, 0, 0, 0, 0], // [skill0, skill1, skill2, skill, skill2, skill]
            }
        };

        // 数据同步到本地
        this.sync_user_data();
    }

    // 计算用户星数
    private _compute_user_star(): void {
        for (let i = 0; i < 3; i++) {
            this.user_data[i].star_num = 0;
            for (let j = 0; j < this.user_data[i].level_info.length; j++) {
                this.user_data[i].star_num += this.user_data[i].level_info[j];
            }
        }
    }
}

export const UG = UGame.Instance;